import cv2
import numpy as np
import os
import operator
from skimage import filters
import matplotlib as mpl
import math
mpl.use('tkagg')
import matplotlib.pyplot as plt
from hhh import judgevertical
class Point(object):
    x =0
    y= 0
    # 定义构造方法
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

class Line(object):
    # a=0
    # b=0
    # c=0
    def __init__(self, p1, p2):
        self.p1 = p1
        self.p2 = p2

def GetLinePara(line):
    line.a =line.p1.y - line.p2.y
    line.b = line.p2.x - line.p1.x
    line.c = line.p1.x *line.p2.y - line.p2.x * line.p1.y
def GetCrossPoint(l1,l2):
    GetLinePara(l1)
    GetLinePara(l2)
    d = l1.a * l2.b - l2.a * l1.b
    p=Point()
    try:
        p.x = (l1.b * l2.c - l2.b * l1.c)*1.0 / d
        p.y = (l1.c * l2.a - l2.c * l1.a)*1.0 / d
    except:
        return -1
    else:
        return p

def touying(img,points):
    rows, cols, ch = img.shape
    pts1 = np.float32(points)
    pts2 = np.float32([[0, 0], [int(cols*1.5) ,0], [0, rows], [int(cols*1.5), rows]])
    M = cv2.getPerspectiveTransform(pts1, pts2)
    dst = cv2.warpPerspective(img, M, (int(cols * 1.5), rows))
    return dst

def readdir(filepath):
    allpath=[]
    pathDir=os.listdir(filepath)
    for allDir in pathDir:
        child=os.path.join('%s%s'%(filepath,allDir))
        allpath.append(child)
    return allpath
def Imgvar(img):                   # 求图像方差
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    dst=cv2.Laplacian(gray,cv2.CV_64F)    #拉普拉斯变换
    imgvar=dst.var()                      #得出方差
    return imgvar
def caltheta(path):
    img=cv2.imread(path)
    imgsize=img.shape[1]
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    drawing = np.zeros(img.shape[:], dtype=np.uint8)
    if imgsize>500 and Imgvar(img)>600:
        gray=cv2.GaussianBlur(gray,(9,9),3)
    else:
        gray = cv2.GaussianBlur(gray, (9, 9), 1)
    thresh = filters.threshold_otsu(gray)
    edges=cv2.Canny(gray,thresh/3,thresh,7)
    lines = cv2.HoughLines(edges,1, np.pi /180,int(thresh),imgsize/11)
    while (lines.shape[0])>100:
        gray = cv2.GaussianBlur(gray, (9, 9), 5)
        thresh = filters.threshold_otsu(gray)
        edges = cv2.Canny(gray,thresh/2, thresh,7)
        lines = cv2.HoughLines(edges, 1, np.pi / 180, int(thresh), imgsize / 11)
    y=[]
    for line in lines:
        rho=line[0][0]
        theta1=line[0][1]
        a = np.cos(theta1)
        b = np.sin(theta1)
        x0 = a * rho
        y0 = b * rho
        x1 = int(x0 + 1000 * (-b))
        y1 = int(y0 + 1000 * (a))
        x2 = int(x0 - 1000 * (-b))
        y2 = int(y0 - 1000 * (a))
        if  (x2-x1)!=0:
            theta=(y1-y2)/(x2-x1)
            if(abs(theta)<1):
                yav=(y1+y2)/2
                xav=(x1+x2)/2
                cv2.line(drawing, (x1, y1), (x2, y2), (0, 255, 0), 1, lineType=cv2.LINE_AA)
                p1 = Point(x1, y1)
                p2 = Point(x2, y2)
                line = Line(p1, p2)
                y.append(line)
    cv2.imshow('a',drawing)
    cv2.waitKey()
    return y
def calpoints(y,img):
    # (x1,y1,x2,y2,theta1),yav=sorted(y.items(),key=operator.itemgetter(1))[0]
    # (xx1,yy1,xx2,yy2, theta2), yav = sorted(y.items(), key=operator.itemgetter(1),reverse=True)[0]
    height,width,chanel=img.shape
    pc=[]
    for i in range(len(y)-1):
        # print(y[i].p1.x,y[i].p1.y,y[i].p2.x,y[i].p2.y)
        for j in range(len(y)-1-i):
            line1=y[i]
            line2=y[i+j]
            if GetCrossPoint(line1, line2)!=-1:
                temp = GetCrossPoint(line1, line2)
                pc.append(temp)
    try:
        Pc=max(set(pc), key=pc.count)
    except:
        l1=Point(0,0)
        l2 = Point(0,height)
        r1 = Point(width,0)
        r2 = Point(width,height)
    else:
        print(Pc.x,Pc.y)
        if Pc.x>width:
            p1 = Point(Pc.x, Pc.y)
            p2 = Point(0, 0)
            line1 = Line(p1, p2)
            l1= GetCrossPoint(line1,Line(Point(0,0),Point(0,5)))
            r1 = GetCrossPoint(line1, Line(Point(width, 0), Point(width, 5)))
            p3 =  Point(Pc.x, Pc.y)
            p4 = Point(0, height)
            line2 = Line(p3, p4)
            l2 = GetCrossPoint(line2, Line(Point(0, 0), Point(0, 5)))
            r2 = GetCrossPoint(line2, Line(Point(width, 0), Point(width, 5)))
        elif Pc.x<0:
            p1 = Point(Pc.x, Pc.y)
            p2 = Point(width, 0)
            line1 = Line(p1, p2)
            l1 = GetCrossPoint(line1, Line(Point(0, 0), Point(0, 5)))
            r1 = GetCrossPoint(line1, Line(Point(width, 0), Point(width, 5)))
            p3 = Point(Pc.x, Pc.y)
            p4 = Point(width, height)
            line2 = Line(p3, p4)
            l2 = GetCrossPoint(line2, Line(Point(0, 0), Point(0, 5)))
            r2 = GetCrossPoint(line2, Line(Point(width, 0), Point(width, 5)))
        else:
            l1 = Point(0, 0)
            l2 = Point(0, height)
            r1 = Point(width, 0)
            r2 = Point(width, height)
    return [[l1.x,l1.y],[r1.x,r1.y],[l2.x,l2.y],[r2.x,r2.y]]

if __name__=='__main__':
    # caltheta('C:/Users/DELL/Desktop/shushida0317-198/JPEGImages/gsk00276.jpg')
    filepath='C:/Users/DELL/Desktop/shushida0322-421/shushida0322-421/new/'
    allpath=readdir(filepath)
    for path in allpath:
        print(path)
        y=caltheta(path)
        img=cv2.imread(path)
        theta, counts = judgevertical.caltheta(path)
        if judgevertical.judge(theta, counts) == 0:
            points=calpoints(y,img)
            dst=touying(img,points)
            iwpath = path.replace('.jpg', '.png')
            cv2.imwrite(iwpath, dst)





